package net.chenlin.dp.ids.server.manager.impl;

import net.chenlin.dp.ids.common.constant.IdsConst;
import net.chenlin.dp.ids.common.entity.SessionData;
import net.chenlin.dp.ids.common.entity.TicketValidateResultDTO;
import net.chenlin.dp.ids.common.util.CommonUtil;
import net.chenlin.dp.ids.common.util.JsonUtil;
import net.chenlin.dp.ids.server.manager.SessionManager;
import net.chenlin.dp.ids.server.util.RedisUtil;
import org.springframework.stereotype.Component;

/**
 * session管理器
 * @author zcl<yczclcn@163.com>
 */
@Component("sessionManager")
public class SessionManagerImpl implements SessionManager {

    /**
     * 更新session过期时间
     * @param sessionId
     * @param loginType
     */
    @Override
    public void update(String sessionId, Integer loginType) {
        // 没有使用记住我设置，访问时刷新 manager redis过期时间
        String redisKey = sessionKey(sessionId, loginType);
        RedisUtil.expire(redisKey, IdsConst.REDIS_EXPIRE_TIME);

    }

    /**
     * 获取sessionData
     * @param sessionId
     * @return
     */
    @Override
    public SessionData get(String sessionId, Integer loginType) {
        String redisKey = sessionKey(sessionId, loginType);
        String json = RedisUtil.get(redisKey);
        return JsonUtil.toObj(json, SessionData.class);
    }

    /**
     * 保存session
     * @param sessionId
     * @param sessionData
     */
    @Override
    public void save(String sessionId, SessionData sessionData) {
        String redisKey = sessionKey(sessionId, sessionData.getLoginType());
        if (sessionData.getRememberMe()) {
            // cookie默认过期时间
            RedisUtil.set(redisKey, JsonUtil.toStr(sessionData), IdsConst.COOKIE_MAX_AGE);
        } else {
            // redis默认过期时间
            RedisUtil.set(redisKey, JsonUtil.toStr(sessionData));
        }
    }

    /**
     * 删除session
     * @param sessionId
     */
    @Override
    public void remove(String sessionId, Integer loginType) {
        String redisKey = sessionKey(sessionId, loginType);
        RedisUtil.del(redisKey);
    }

    /**
     * 保存ticket
     * @param ticket
     * @param loginType
     * @param sessionId
     */
    @Override
    public void saveTicket(String ticket, Integer loginType, String sessionId) {
        RedisUtil.set(getTicketRedisKey(ticket.toLowerCase()), sessionId, IdsConst.TICKET_EXPIRE_TIME);
    }

    /**
     * 校验ticket合法性
     * @param ticket
     * @param loginType
     * @return
     */
    @Override
    public TicketValidateResultDTO validateTicket(String ticket, Integer loginType) {
        String ticketKey = getTicketRedisKey(ticket.toLowerCase());
        String sessionId = RedisUtil.get(ticketKey);
        if (CommonUtil.strIsEmpty(sessionId)) {
            return null;
        }
        // 删除ticket，每个ticket只能使用一次
        RedisUtil.del(ticketKey);
        String sessionDataJson = RedisUtil.get(sessionKey(sessionId, loginType));
        if (CommonUtil.strIsNotEmpty(sessionDataJson)) {
            SessionData sessionData = JsonUtil.toObj(sessionDataJson, SessionData.class);
            return new TicketValidateResultDTO(sessionId, sessionData.getRememberMe(), sessionData.getLoginType());
        }
        return null;
    }

    /**
     * sessionKey
     * @param sessionId
     * @return
     */
    private String sessionKey(String sessionId, Integer loginType) {
        StringBuilder sb = new StringBuilder(IdsConst.REDIS_SESSION_KEY);
        if (IdsConst.LOGIN_TYPE_WEB == loginType) {
            sb.append("web:");
        }
        if (IdsConst.LOGIN_TYPE_APP == loginType) {
            sb.append("app:");
        }
        sb.append("session:").append(sessionId);
        return sb.toString();
    }

    /**
     * 构造ticket-redisKey
     * @param ticket
     * @return
     */
    private String getTicketRedisKey(String ticket) {
        return IdsConst.REDIS_SESSION_KEY + "ticket:" + ticket;
    }

}
